package org.jeecg.modules.online.graphreport.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.vo.DictModel;
import org.jeecg.common.util.BrowserUtils;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.online.graphreport.entity.OnlGraphreportHead;
import org.jeecg.modules.online.graphreport.entity.OnlGraphreportItem;
import org.jeecg.modules.online.graphreport.service.IOnlGraphreportApiService;
import org.jeecg.modules.online.graphreport.service.IOnlGraphreportHeadService;
import org.jeecg.modules.online.graphreport.util.GraphreportUtil;
import org.jeecgframework.poi.excel.ExcelExportUtil;
import org.jeecgframework.poi.excel.entity.ExportParams;
import org.jeecgframework.poi.excel.entity.params.ExcelExportEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Title: Controller
 * @Description: 图表报告
 * @Author:jeecg-boot
 * @Date: 2019-04-11
 * @Version:V1.0
 */
@RestController("onlGraphreportApiController")
@RequestMapping("/online/graphreport/api")
@Slf4j
public class OnlGraphreportApiController {

	@Autowired
	private IOnlGraphreportHeadService headService;
	@Autowired
	private IOnlGraphreportApiService apiService;

	/**
	 * 获取多数据源模板图表数据
	 */
	@GetMapping(value = "/getTempletAllData")
	public Result<?> getTempletAllData(@RequestParam(name = "id", required = true) String id) {
		return apiService.getTempletChartsData(id);
	}

	/**
	 * 获取图表数据
	 * 
	 * @param id
	 * @return
	 */
	@GetMapping(value = "/getChartsData")
	public Result<?> getChartsData(@RequestParam(name = "id", required = true) String id, @RequestParam("params") String paramString) {
		OnlGraphreportHead head = headService.getById(id);
		if (head == null) {
			return Result.error("实体不存在");
		} else {
			return Result.ok(apiService.queryChartDataSource(head, paramString));
		}
	}

	/**
	 * 根据code获取图表数据
	 * 
	 * @param code
	 * @return
	 */
	@GetMapping(value = "/getChartsDataByCode")
	public Result<?> getChartsDataByCode(@RequestParam(name = "code", required = true) String code, @RequestParam("params") String paramString) {
		OnlGraphreportHead head = headService.queryByCode(code);
		if (head == null) {
			return Result.error("实体不存在");
		} else {
			return Result.ok(apiService.queryChartDataSource(head, paramString));
		}
	}

	/**
	 * 导出excel（后台查询数据）
	 *
	 * @throws Exception
	 */
	@RequestMapping(value = "/exportXlsById")
	public void exportXlsById(
			@RequestParam("id") String id,
			@RequestParam(value = "name", required = false) String name,
			@RequestParam(value = "params", required = false) String paramString,
			HttpServletRequest request,
			HttpServletResponse response
	) {
		OnlGraphreportHead head = headService.getById(id);
		if (head == null) {
			throw new JeecgBootException("实体不存在");
		}
		if (oConvertUtils.isEmpty(name)) {
			name = "ExportExcel";
		}
		// 【step.1】 根据 headId 查询出data、items、dictOptions
		Map<String, Object> dataMap = apiService.queryChartDataSource(head, paramString);
		List<Map<String, Object>> dataSource;
		// JSON数据源获取数据
		if ("json".equals(head.getDataType())) {
			Type type = new TypeReference<List<Map<String, Object>>>() {
			}.getType();
			dataSource = JSON.parseArray(head.getCgrSql()).toJavaObject(type);
		} else {
			//noinspection unchecked
			dataSource = (List<Map<String, Object>>) dataMap.get("data");
		}
		@SuppressWarnings("unchecked")
		List<OnlGraphreportItem> items = (List<OnlGraphreportItem>) dataMap.get("items");
		@SuppressWarnings("unchecked")
		Map<String, List<DictModel>> dictOptions = (Map<String, List<DictModel>>) dataMap.get("dictOptions");
		// 【step.2】 根据 items 装载 entity list，同时取出需要计算总计的字段
		List<ExcelExportEntity> entityList = new ArrayList<>();
		// 计算总计的字段
		Map<String, Double> totalFields = new HashMap<>();
		// 序号字段
		final String TABLE_NUM_FIELD = "table_left_num_index";
		entityList.add(new ExcelExportEntity("#", TABLE_NUM_FIELD, 30));
		for (OnlGraphreportItem item : items) {
			if ("Y".equals(item.getIsShow())) {
				String key = item.getFieldName();
				String alias = item.getFieldTxt();
				// 默认宽度30
				entityList.add(new ExcelExportEntity(alias, key, 30));
				// 判断是否计算总数
				if ("Y".equals(item.getIsTotal())) {
					totalFields.put(key, 0.0);
				}
			}
		}
		// 【step.2】 遍历 dataSource 填充序号列、翻译数据、计算总计
		for (int i = 0; i < dataSource.size(); i++) {
			Map<String, Object> data = dataSource.get(i);
			// 序号字段
			data.put(TABLE_NUM_FIELD, i + 1);
			// 计算总计
			if (totalFields.size() > 0) {
				for (String totalKey : totalFields.keySet()) {
					try {
						if (oConvertUtils.isNotEmpty(data.get(totalKey))) {
							double doubleValue = Double.parseDouble(String.valueOf(data.get(totalKey)));
							totalFields.put(totalKey, totalFields.get(totalKey) + doubleValue);
						}
					} catch (Exception e) {
						log.error("导出计算总计时出错：", e);
						// parseDouble出错，可能是包含非数字内容，取消该列的总计
						totalFields.remove(totalKey);
					}
				}
			}
			// 翻译字段
			if (dictOptions.keySet().size() > 0) {
				for (String fieldName : dictOptions.keySet()) {
					List<DictModel> dictList = dictOptions.get(fieldName);
					String originValue = String.valueOf(data.get(fieldName));
					String translValue = GraphreportUtil.filterDictText(dictList, originValue);
					data.put(fieldName, translValue);
				}
			}
		}
		// 如果有计算总计的列，就新增加一行来展示总计数据
		if (totalFields.size() > 0) {
			Map<String, Object> data = new HashMap<>();
			data.put(TABLE_NUM_FIELD, "总计");
			for (String totalKey : totalFields.keySet()) {
				data.put(totalKey, totalFields.get(totalKey));
			}
			dataSource.add(data);
		}

		ServletOutputStream out = null;
		try {
			// 导出Execl
			Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(name, name), entityList, dataSource);
			// step.4 根据浏览器进行转码，使其支持中文文件名
			String browse = BrowserUtils.checkBrowse(request);
			if ("MSIE".equalsIgnoreCase(browse.substring(0, 4))) {
				response.setHeader("content-disposition", "attachment;filename=" + java.net.URLEncoder.encode(name, "UTF-8") + ".xls");
			} else {
				String newtitle = new String(name.getBytes(StandardCharsets.UTF_8), "ISO8859-1");
				response.setHeader("content-disposition", "attachment;filename=" + newtitle + ".xls");
			}
			// 写出到view
			out = response.getOutputStream();
			workbook.write(out);
		} catch (Exception ignored) {
		} finally {
			try {
				if (out != null) {
					out.flush();
					out.close();
				}
			} catch (Exception ignored) {
			}
		}
	}

//	/**
//	 * 导出excel
//	 *
//	 * @throws Exception
//	 */
//	@RequestMapping(value = "/exportXls")
//	public void exportXls(HttpServletRequest request, HttpServletResponse response) throws Exception {
//		// 取参数
//		String name = request.getParameter("name");
//		String dataSourceString = URLDecoder.decode(request.getParameter("dataSource"), "UTF-8");
//		String entitysString = URLDecoder.decode(request.getParameter("entitys"), "UTF-8");
//
//		// 非空判断
//		if (StringUtil.isEmpty(dataSourceString) || StringUtil.isEmpty(entitysString)) {
//			throw new Exception("缺少必要的参数（dataSource、entitys）");
//		}
//		if (StringUtil.isEmpty(name)) {
//			name = "ExportExecel";
//		}
//		// 转为JSONArray
//		JSONArray entitysJson = JSONObject.parseArray(entitysString);
//		JSONArray dataSourceJson = JSONObject.parseArray(dataSourceString);
//
//		// 装载 entity
//		List<ExcelExportEntity> entityList = new ArrayList<ExcelExportEntity>();
//		for (int i = 0; i < entitysJson.size(); i++) {
//			JSONObject entity = entitysJson.getJSONObject(i);
//			String key = entity.getString("key");
//			String alias = entity.getString("alias");
//			// 默认宽度30
//			entityList.add(new ExcelExportEntity(alias, key, 30));
//		}
//
//		// 装载 list
//		List<Map<String, String>> list = new ArrayList<Map<String, String>>();
//		for (int i = 0; i < dataSourceJson.size(); i++) {
//			JSONObject data = dataSourceJson.getJSONObject(i);
//			// 遍历 keys
//			Iterator<String> iterator = data.keySet().iterator();
//			Map<String, String> map = new HashMap<String, String>();
//			while (iterator.hasNext()) {
//				String key = (String) iterator.next();
//				String value = data.getString(key);
//				map.put(key, value);
//			}
//			list.add(map);
//		}
//
//		ServletOutputStream out = null;
//		try {
//
//			// 导出Execl
//			Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(name, name), entityList, list);
//
//			// step.4 根据浏览器进行转码，使其支持中文文件名
//			String browse = BrowserUtils.checkBrowse(request);
//			if ("MSIE".equalsIgnoreCase(browse.substring(0, 4))) {
//				response.setHeader("content-disposition", "attachment;filename=" + java.net.URLEncoder.encode(name, "UTF-8") + ".xls");
//			} else {
//				String newtitle = new String(name.getBytes("UTF-8"), "ISO8859-1");
//				response.setHeader("content-disposition", "attachment;filename=" + newtitle + ".xls");
//			}
//
//			// 写出到view
//			out = response.getOutputStream();
//			workbook.write(out);
//		} catch (Exception e) {
//		} finally {
//			try {
//				out.flush();
//				out.close();
//			} catch (Exception e) {
//			}
//		}
//
//	}

}
